#include <iostream>
#include <algorithm>
#include <Poco/Thread.h>
#include <Poco/Net/TCPServer.h>
#include "Poco/Net/StreamSocket.h"
#include <Poco/Net/TCPServerParams.h>
#include <Poco/Net/TCPServerConnectionFactory.h>

#define MAX_THREADS_NUM 16
#define PORT 28888
#define SLEEP_INTERVAL 1000

using Poco::Net::TCPServer;
 
using Poco::Net::StreamSocket;
using Poco::Net::TCPServerConnection;
using Poco::Net::TCPServerConnectionFactory;

class InputReverseServerConnection : public TCPServerConnection{
public:
    InputReverseServerConnection(const StreamSocket& socket) : TCPServerConnection(socket) {}

    void run() override  {
        unsigned char m_buf[257] = { 0 };
        decltype(auto) ss = socket();

        int n = ss.receiveBytes(m_buf, sizeof(m_buf));
        if (n > 2) {
            std::reverse(m_buf, m_buf + n - 2);
            ss.sendBytes(m_buf, n);
        }
    }
};

class InputReverseServerConnectionFactory : public TCPServerConnectionFactory{
public:
    InputReverseServerConnection* createConnection(const StreamSocket& socket) override{
        return new InputReverseServerConnection(socket);
    }
};

int main(int argc, const char* argv[])
{
    try {
        Poco::Net::TCPServerParams* serverParams = new Poco::Net::TCPServerParams();
        serverParams->setMaxThreads(MAX_THREADS_NUM);

        TCPServer server(new InputReverseServerConnectionFactory(), PORT, serverParams);
        server.start();

        while (true){
            Poco::Thread::sleep(SLEEP_INTERVAL);
        }

        // following code will never execute
        //server.stop();
    }
    catch (const Poco::Exception& exc) {
        std::cerr << "Exception thrown: " << exc.displayText() << std::endl;
    }
    catch (const std::exception& exc) {
        std::cerr << "Exception thrown: " << exc.what() << std::endl;
    }
    return 0;
}
